Add scheduled workflow to update all plugins daily#7406
Conversation
Runs checkPlugin with autopush on all ether/ep_* repos daily at 06:00 UTC. Updates workflows, dependencies, linting, and version bumps across all plugins. Requires PLUGINS_PAT org secret with push access to all ep_* repos. Can also be triggered manually via workflow_dispatch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Review Summary by QodoAdd scheduled workflow to update all plugins daily
WalkthroughsDescription• Adds GitHub Actions workflow for daily automated plugin updates • Runs checkPlugin autopush on all ether/ep_* repositories daily at 06:00 UTC • Supports manual triggering via workflow_dispatch for on-demand updates • Requires PLUGINS_PAT organization secret with push access to plugin repos Diagramflowchart LR
schedule["Daily Schedule<br/>06:00 UTC"] --> workflow["Update Plugins<br/>Workflow"]
manual["Manual Trigger<br/>workflow_dispatch"] --> workflow
workflow --> setup["Setup Environment<br/>Node.js, pnpm"]
setup --> git["Configure Git<br/>with PAT"]
git --> list["List all ep_*<br/>Repositories"]
list --> loop["Clone/Pull &<br/>checkPlugin autopush"]
loop --> result["Update Commits<br/>Pushed to Repos"]
File Changes1. .github/workflows/update-plugins.yml
|
Code Review by Qodo
1. Scheduled workflow runs by default
|
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Check out etherpad-lite | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - uses: pnpm/action-setup@v3 | ||
| name: Install pnpm | ||
| with: | ||
| version: 10 | ||
| run_install: false | ||
|
|
||
| - name: Use Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 22 | ||
|
|
||
| - name: Install bin dependencies | ||
| working-directory: ./bin | ||
| run: pnpm install | ||
|
|
||
| - name: Configure git | ||
| run: | | ||
| git config --global user.name 'github-actions[bot]' | ||
| git config --global user.email '41898282+github-actions[bot]@users.noreply.github.com' | ||
|
|
||
| - name: Clone and update all plugins | ||
| env: | ||
| GH_TOKEN: ${{ secrets.PLUGINS_PAT }} | ||
| run: | | ||
| # Configure git to use the PAT for all ether/ repos | ||
| git config --global url."https://x-access-token:${GH_TOKEN}@github.com/ether/".insteadOf "https://github.com/ether/" | ||
|
|
||
| cd .. | ||
| # List all ep_* repos from ether org | ||
| plugins=$(gh repo list ether --limit 200 --json name --jq '.[] | select(.name | startswith("ep_")) | .name') | ||
|
|
||
| for plugin in $plugins; do | ||
| echo "============================================================" | ||
| echo "Processing $plugin" | ||
| echo "============================================================" | ||
|
|
||
| # Clone if not present | ||
| if [ ! -d "$plugin" ]; then | ||
| git clone "https://github.com/ether/${plugin}.git" "$plugin" || { echo "SKIP: clone failed"; continue; } | ||
| fi | ||
|
|
||
| # Pull latest | ||
| (cd "$plugin" && git pull --ff-only) || { echo "SKIP: pull failed"; continue; } | ||
|
|
||
| # Run checkPlugin with autopush | ||
| cd etherpad-lite/bin | ||
| pnpm run checkPlugin "$plugin" autopush 2>&1 | tail -20 || echo "WARN: checkPlugin failed for $plugin" | ||
| cd ../.. | ||
| done |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
| on: | ||
| schedule: | ||
| - cron: '0 6 * * *' # Daily at 06:00 UTC | ||
| workflow_dispatch: # Allow manual trigger |
There was a problem hiding this comment.
1. Scheduled workflow runs by default 📘 Rule violation ☼ Reliability
The new workflow is enabled on a daily cron schedule, changing default behavior without an enable/disable mechanism. This violates the requirement that new features be gated behind a feature flag and disabled by default.
Agent Prompt
## Issue description
The scheduled GitHub Actions workflow is enabled by default via `on.schedule`, which introduces new automatic behavior without a feature flag.
## Issue Context
The workflow performs automated plugin updates with `autopush`, so it should be explicitly enabled (disabled by default) to comply with the feature-flag requirement.
## Fix Focus Areas
- .github/workflows/update-plugins.yml[3-6]
- .github/workflows/update-plugins.yml[35-63]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| cd etherpad-lite/bin | ||
| pnpm run checkPlugin "$plugin" autopush 2>&1 | tail -20 || echo "WARN: checkPlugin failed for $plugin" |
There was a problem hiding this comment.
2. Pipeline hides failures 🐞 Bug ≡ Correctness
The checkPlugin command is piped to tail, so the workflow step uses tail’s exit code and can report success even when checkPlugin fails for a plugin. This can silently skip updates/pushes while still printing only the last 20 lines of output.
Agent Prompt
### Issue description
The workflow pipes `pnpm run checkPlugin ...` into `tail`, which masks `checkPlugin` failures because the pipeline exit code becomes `tail`'s exit code.
### Issue Context
`bin/plugins/checkPlugin.ts` is designed to fail the process on errors (throws/unhandled rejection) and only calls `process.exit(0)` on success. The workflow should therefore propagate the actual command exit status.
### Fix Focus Areas
- .github/workflows/update-plugins.yml[59-62]
### Suggested fix
- Add `set -euo pipefail` at the start of the run block.
- Replace the pipeline with an approach that keeps the original exit code, e.g.:
- Capture output and status:
- `out=$(pnpm run checkPlugin "$plugin" autopush 2>&1); status=$?; echo "$out" | tail -20; [ $status -eq 0 ] || { echo "WARN: ..."; continue; }`
- Or use `tee` plus `PIPESTATUS[0]` under bash with `pipefail`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
|
||
| cd .. | ||
| # List all ep_* repos from ether org | ||
| plugins=$(gh repo list ether --limit 200 --json name --jq '.[] | select(.name | startswith("ep_")) | .name') |
There was a problem hiding this comment.
3. Repo list truncation 🐞 Bug ≡ Correctness
The workflow only lists the first 200 repos from the ether org, so any additional ep_* repos beyond that will never be processed. This breaks the stated goal of updating all ether/ep_* plugins daily.
Agent Prompt
### Issue description
The workflow enumerates repos with `gh repo list ... --limit 200`, which can omit `ep_*` repos beyond the first 200.
### Issue Context
This workflow intends to update *all* `ether/ep_*` repos. Existing scripts in `bin/plugins/` already show multi-page enumeration patterns.
### Fix Focus Areas
- .github/workflows/update-plugins.yml[43-45]
### Suggested fix
Use a paginated API call instead of a fixed limit, for example:
- `plugins=$(gh api --paginate 'orgs/ether/repos?per_page=100' --jq '.[].name | select(startswith("ep_"))')`
Or raise the limit to a sufficiently high value *and* confirm it truly covers all repos.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| plugins=$(gh repo list ether --limit 200 --json name --jq '.[] | select(.name | startswith("ep_")) | .name') | ||
|
|
||
| for plugin in $plugins; do |
There was a problem hiding this comment.
4. Core repo not excluded 🐞 Bug ≡ Correctness
The workflow processes every repo whose name starts with ep_ without excluding ep_etherpad-lite, which existing plugin automation explicitly skips. If ep_etherpad-lite is present in the org, this workflow could create automated commits/pushes to that repo unintentionally.
Agent Prompt
### Issue description
The workflow processes every `ep_*` repo and does not skip `ep_etherpad-lite`, unlike existing plugin automation.
### Issue Context
`checkPlugin` with `autopush` can modify files, commit, and push. Existing scripts/docs treat `ep_etherpad-lite` as a special-case repo to skip.
### Fix Focus Areas
- .github/workflows/update-plugins.yml[44-46]
### Suggested fix
Add an explicit exclusion in the filter or in the loop, e.g.:
- In jq: `select(.name | startswith("ep_") and .name != "ep_etherpad-lite")`
- Or in bash: `[[ "$plugin" == "ep_etherpad-lite" ]] && continue`
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Summary
ether/ep_*repos and runscheckPlugin autopushon eachpnpm update), linting, and version bumpsSetup required
Create a
PLUGINS_PATorg secret at https://github.com/organizations/ether/settings/secrets/actions with a Personal Access Token that has push access to allether/ep_*repos (needsreposcope or fine-grained with contents write access to the ether org).Test plan
🤖 Generated with Claude Code